package com.doctor.comm;

/* 
 * android4.4+版本的扩展sd卡文件操作
 * Copyright (C) 2014 NextApp, Inc. 
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 *  
 * http://www.apache.org/licenses/LICENSE-2.0 
 *  
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" 
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language 
 * governing permissions and limitations under the License. 
 */
  
import java.io.File;  
import java.io.IOException;  
import java.io.OutputStream;  
  
import android.content.ContentResolver;  
import android.content.ContentValues;  
import android.net.Uri;  
import android.provider.MediaStore;  
  
/** 
 * Wrapper for manipulating files via the Android Media Content Provider. As of Android 4.4 KitKat, applications can no longer write 
 * to the "secondary storage" of a device. Write operations using the java.io.File API will thus fail. This class restores access to 
 * those write operations by way of the Media Content Provider. 
 *  
 * Note that this class relies on the internal operational characteristics of the media content provider API, and as such is not 
 * guaranteed to be future-proof. Then again, we did all think the java.io.File API was going to be future-proof for media card 
 * access, so all bets are off. 
 *  
 * If you're forced to use this class, it's because Google/AOSP made a very poor API decision in Android 4.4 KitKat. 
 * Read more at https://plus.google.com/+TodLiebeck/posts/gjnmuaDM8sn 
 * 
 * Your application must declare the permission "android.permission.WRITE_EXTERNAL_STORAGE". 
 */  
public class MediaFile {  
  
    private final File file;  
    private final ContentResolver contentResolver;  
    private final Uri filesUri;  
    private final Uri imagesUri;  
  
    public MediaFile(ContentResolver contentResolver, File file) {  
        this.file = file;  
        this.contentResolver = contentResolver;  
        filesUri = MediaStore.Files.getContentUri("external");  
        imagesUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;  
    }  
  
    /** 
     * Deletes the file. Returns true if the file has been successfully deleted or otherwise does not exist. This operation is not 
     * recursive. 
     */  
    public boolean delete()  
            throws IOException {  
        if (!file.exists()) {  
            return true;  
        }  
  
        boolean directory = file.isDirectory();  
        if (directory) {  
            // Verify directory does not contain any files/directories within it.  
            String[] files = file.list();  
            if (files != null && files.length > 0) {  
                return false;  
            }  
        }  
  
        String where = MediaStore.MediaColumns.DATA + "=?";  
        String[] selectionArgs = new String[] { file.getAbsolutePath() };  
  
        // Delete the entry from the media database. This will actually delete media files (images, audio, and video).  
        contentResolver.delete(filesUri, where, selectionArgs);  
  
        if (file.exists()) {  
            // If the file is not a media file, create a new entry suggesting that this location is an image, even  
            // though it is not.  
            ContentValues values = new ContentValues();  
            values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());  
            contentResolver.insert(imagesUri, values);  
  
            // Delete the created entry, such that content provider will delete the file.  
            contentResolver.delete(filesUri, where, selectionArgs);  
        }  
  
        return !file.exists();  
    }  
  
    public File getFile() {  
        return file;  
    }  
  
    /** 
     * Creates a new directory. Returns true if the directory was successfully created or exists. 
     */  
    public boolean mkdir()  
            throws IOException {  
        if (file.exists()) {  
            return file.isDirectory();  
        }  
  
        ContentValues values;  
        Uri uri;  
  
        // Create a media database entry for the directory. This step will not actually cause the directory to be created.  
        values = new ContentValues();  
        values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());  
        contentResolver.insert(filesUri, values);  
  
        // Create an entry for a temporary image file within the created directory.  
        // This step actually causes the creation of the directory.  
        values = new ContentValues();  
        values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath() + "/temp.jpg");  
        uri = contentResolver.insert(imagesUri, values);  
  
        // Delete the temporary entry.  
        contentResolver.delete(uri, null, null);  
  
        return file.exists();  
    }  
  
    /** 
     * Returns an OutputStream to write to the file. The file will be truncated immediately. 
     */  
    public OutputStream write()  
            throws IOException {  
        if (file.exists() && file.isDirectory()) {  
            throw new IOException("File exists and is a directory.");  
        }  
  
        // Delete any existing entry from the media database.  
        // This may also delete the file (for media types), but that is irrelevant as it will be truncated momentarily in any case.  
        String where = MediaStore.MediaColumns.DATA + "=?";  
        String[] selectionArgs = new String[] { file.getAbsolutePath() };  
        contentResolver.delete(filesUri, where, selectionArgs);  
  
        ContentValues values = new ContentValues();  
        values.put(MediaStore.Files.FileColumns.DATA, file.getAbsolutePath());  
        Uri uri = contentResolver.insert(filesUri, values);  
  
        if (uri == null) {  
            // Should not occur.  
            throw new IOException("Internal error.");  
        }  
  
        return contentResolver.openOutputStream(uri);  
    }  
}
